<template>
    <div class="default-route">
        <nav>
            <Tabs v-model="state.currentTab" @tab-click="tabClick" />
            <div class="right_btn">
                <el-button v-auth="'commodity:sync'" plain @click="onSyncErp">
                    同步商品至ERP
                    <el-tooltip
                        effect="dark"
                        placement="top"
                        content="同步之前请先确保商品填写【外部SPU编码】和【外部SKU编码】，否则无法同步至ERP。">
                        <div class="icon-img">
                            <img src="@/assets/imgs/sys/question-circle.png" />
                            <img src="@/assets/imgs/sys/question-circle_active.png" />
                        </div>
                    </el-tooltip>
                </el-button>
                <el-button v-auth="'commodity:add'" type="primary" @click="addGoods">发布商品 </el-button>
            </div>
        </nav>
        <Filter v-model="state.searchParams" @search="onSearch" @reset="onReset" />
        <TableHeaderBtn :currentTab="state.currentTab" @batch="batchHandle" v-on:setShowRule="setShowRuleHandle" />
        <Table
            ref="TableRef"
            v-loading="state.loading"
            :data="state.list"
            stripe
            style="width: 100%"
            @sort-change="sortChangeHandle"
            @selection-change="handleSelectionChange"
            :list="state.list"
            :currentTab="state.currentTab"
            @change="getList" />
        <div class="pagination zw-pagination">
            <Pagination
                :total="state.totalCount"
                :page-size="state.searchParams.pageSize"
                :current-page="state.searchParams.pageNum"
                @sizeChange="sizeChangeHandle"
                @pageChange="pageChangeHandle" />
        </div>
        <!-- 批量操作确认弹窗 -->
        <ConfirmDialog :data="confirmDiaProps" @confirm="batchConfirmHandle(state.type)" />
        <!-- 批量上架错误时弹窗 -->
        <ErrorDialog ref="ErrorDialogRef" />
        <!-- 设置展示规则弹窗 -->
        <SetShowRuleDia ref="SetShowRuleDiaRef" v-on:success="setShowRuleSuccess" />
        <!-- Erp 同步关闭弹窗 -->
        <ConfirmDialog :data="confirmErpDiaProps" @closed="onSyncDone">
            <template #footer>
                <el-button @click="onSyncDone">关闭 </el-button>
            </template>
        </ConfirmDialog>
    </div>
</template>

<script setup>
import Tabs from './tabs.vue';
import Filter from './filter.vue';
import TableHeaderBtn from './tableHeaderBtn.vue';
import Table from './table.vue';
import ErrorDialog from './errorDia.vue';
import Pagination from '@/components/Pagination.vue';
import SetShowRuleDia from './setShowRuleDia.vue';
import ConfirmDialog from '@/components/ConfirmDialog.vue';

import request from '@/request';
import { getGoodsListHook } from '@/hooks/goods';
import store from '@/store';
import storage from '@/commons/storage';
import { getIdsArr, throttle, humpToUnderline, cloneDeep, floatMultiply, isNotEmpty } from '@/commons/utils';

import { ElLoading, ElMessage } from 'element-plus';
import { useRouter } from 'vue-router';
import { reactive, ref, nextTick, onMounted } from 'vue';

const router = useRouter();
const useCommodityStore = store.useCommodityStore();
const form = {
    // 商品编号
    keywords: '',
    // 商品类目 ID
    classId: 0,
    // 商品分组 ID
    categoryId: 0,
    // 价格左边
    priceLeft: void 0,
    // 价格右边
    priceRight: void 0,
    // 库存搜索左边
    goodsStockSmall: void 0,
    // 库存搜索右边
    goodsStockBig: void 0,
    // 	销量左边
    sellLeft: void 0,
    // 销量右边
    sellRight: void 0,
    // 1 展示 2 不展示
    isShow: 0,
    // 排序的字段（库存goods_sku、总销量goods_sales_number、创建时间created_at、上架时间up_shelf_at）
    orderByColumn: '',
    // 排序方向：asc 升序  desc 倒序
    orderByDirection: '',
    // 1销售中  2仓库  3 售罄
    onSale: useCommodityStore.currentTab == 1 ? 1 : useCommodityStore.currentTab == 2 ? 3 : 2,
    // 当前页
    pageNum: 1,
    // 一页多少条
    pageSize: 10,
    // 店铺 id
    shopId: storage.get('ZW-SHOPID')
};
const state = reactive({
    // 商品列表
    list: [],
    // 总条数
    totalCount: 0,
    // 1:销售中 2:已售罄 3:仓库中
    currentTab: useCommodityStore.currentTab,
    // 表格 loading
    loading: false,
    // 批量操作类型
    type: '',
    searchParams: cloneDeep(form)
});
// 解决输入框输入未点击查询时点击排序不需要带上筛选条件
const searchParamsCopy = cloneDeep(form);
// 表格实例方法
/* --------------------------------------------------------- 表格实例方法 start --------------------------------------------------------- */
const TableRef = ref(null);
// 清除多选
const clearSelectionHandle = () => {
    TableRef.value.$refs.tableRef.clearSelection();
};
// 清除排序
const clearSortHandle = () => {
    TableRef.value.$refs.tableRef.clearSort();
};
/* --------------------------------------------------------- 表格实例方法 end --------------------------------------------------------- */

/* --------------------------------------------------------- 列表筛选 start --------------------------------------------------------- */
// 区间传参数转换为后端想要的
const paramFormatHandle = obj => {
    const [leftKey, rightKey] = Object.keys(obj);
    let [left, right] = Object.values(obj);
    left = left || 0;
    right = right === 0 ? 0 : right || 99999999;
    if (left > right) {
        state.searchParams[leftKey] = right;
        state.searchParams[rightKey] = left;
        return [right, left];
    }
    return [left, right];
};
// 获取列表
const getList = async () => {
    ['orderByColumn', 'orderByDirection', 'onSale', 'pageNum', 'pageSize'].forEach(key => {
        searchParamsCopy[key] = state.searchParams[key];
    });
    const params = {};
    // 过滤除 0 外的假值
    for (const [key, value] of Object.entries(searchParamsCopy)) {
        if (value || value === 0) params[key] = value;
    }
    // select 选择全部不传该字段
    ['categoryId', 'classId', 'isShow'].forEach(key => {
        if (params[key] === 0) delete params[key];
    });
    const { goodsStockSmall, goodsStockBig, priceLeft, priceRight, sellLeft, sellRight } = params;
    const stock = paramFormatHandle({ goodsStockSmall, goodsStockBig });
    const price = paramFormatHandle({ priceLeft, priceRight });
    const sell = paramFormatHandle({ sellLeft, sellRight });
    params.goodsStockSmall = stock[0];
    params.goodsStockBig = stock[1];
    params.price = [+floatMultiply(price[0]), +floatMultiply(price[1])];
    params.sell = sell;
    ['priceLeft', 'priceRight', 'sellLeft', 'sellRight'].forEach(key => {
        delete params[key];
    });
    state.loading = true;
    try {
        const { data } = await getGoodsListHook(params);
        state.loading = false;
        const list = Array.isArray(data.list) ? data.list : [];
        state.list = list.map(item => {
            // 商品分组数据转换
            let arr = [];
            item.category.forEach(el => {
                arr.push(el.categorySonId);
            });
            arr = arr.filter(Boolean);
            item.categoryName = arr.join('；');
            item.categoryNameText = item.categoryName || '-';
            return item;
        });
        state.totalCount = data.totalCount || 0;
    } catch (error) {}
    state.loading = false;
};
// 查询
const onSearch = () => {
    Object.assign(searchParamsCopy, state.searchParams);
    getList();
};
// 清空
const onReset = v => {
    clearSortHandle();
    // 不重置 onSale
    const onSale = state.searchParams.onSale;
    state.searchParams = cloneDeep(form);
    state.searchParams.onSale = onSale;
    Object.assign(searchParamsCopy, state.searchParams);
    getList();
};
// 一页多少条
const sizeChangeHandle = v => {
    state.searchParams.pageNum = 1;
    state.searchParams.pageSize = v;
    getList();
};
// 当前页
const pageChangeHandle = v => {
    state.searchParams.pageNum = v;
    getList();
};
/* --------------------------------------------------------- 列表筛选 end --------------------------------------------------------- */
// 当前选中的每一行 row
let multipleSelection = [];
const handleSelectionChange = v => {
    multipleSelection = v;
};
// 当前列表是否勾选校验
const onSelectionLengthValidate = () => {
    if (multipleSelection.length === 0) {
        ElMessage.error('请至少选择一件商品！');
        return false;
    }
    return true;
};

/* --------------------------------------------------------- 排序 start --------------------------------------------------------- */

const sortChangeHandle = ({ column, prop, order }) => {
    const orderMap = { descending: 'desc', ascending: 'asc' };
    state.searchParams.orderByDirection = orderMap[order] || '';
    state.searchParams.orderByColumn = orderMap[order] ? humpToUnderline(prop) : '';
    getList();
};
/* --------------------------------------------------------- 排序 end --------------------------------------------------------- */

/* --------------------------------------------------------- 批量 上架｜下架｜删除 start --------------------------------------------------------- */
const confirmDiaProps = reactive({
    show: false,
    title: '',
    content: ''
});
// 显示确认弹窗
const onShowConfirmDia = type => {
    state.type = type;
    const textObj = {
        putaway: '批量上架',
        shelves: '批量下架',
        delete: '批量删除'
    };
    confirmDiaProps.title = textObj[type];
    confirmDiaProps.content = `确定要${textObj[type]}所选商品吗？`;
    confirmDiaProps.show = true;
};
// 商品信息缺失弹窗
const ErrorDialogRef = ref(null);
// 批量上架
const shelvesHandle = async goodsId => {
    return new Promise((resolve, reject) => {
        const params = { goodsId, onSale: state.currentTab == 3 ? 1 : 2 };
        request('shelfGoodsServ', params).then(res => {
            if (res.code === 0) {
                resolve();
            } else if (isNotEmpty(res.data)) {
                confirmDiaProps.show = false;
                ErrorDialogRef.value.onOpen(res.data);
                reject();
            } else {
                ElMessage.error(res.msg);
            }
        });
    });
};
// 批量删除
const deleteHandle = async goodIds => {
    return new Promise((resolve, reject) => {
        request('deleteBatchGoodsServ', { goodIds }).then(res => {
            if (res.code === 0) {
                return resolve();
            } else {
                ElMessage.error(res.msg);
                reject();
            }
        });
    });
};
// 批量操作确认
const batchConfirmHandle = async type => {
    const ids = getIdsArr(multipleSelection);
    if (['putaway', 'shelves'].includes(type)) await shelvesHandle(ids);
    if (type === 'delete') await deleteHandle(ids);
    multipleSelection = [];
    confirmDiaProps.show = false;
    const messageText = `${confirmDiaProps.title}成功`;
    ElMessage.success(messageText);
    getList();
};

// 批量 上架|下架|删除
const batchHandle = async type => {
    if (!onSelectionLengthValidate()) return;
    onShowConfirmDia(type);
};
/* --------------------------------------------------------- 批量 上架｜下架｜删除 end --------------------------------------------------------- */

/* --------------------------------------------------------- 设置展示规则 start --------------------------------------------------------- */
// 设置展示规则
const SetShowRuleDiaRef = ref(null);
const setShowRuleHandle = () => {
    if (!onSelectionLengthValidate()) return;
    const ids = getIdsArr(multipleSelection);
    SetShowRuleDiaRef.value.openDialog(ids);
};
const setShowRuleSuccess = () => {
    clearSelectionHandle();
    getList();
};
/* --------------------------------------------------------- 设置展示规则 end --------------------------------------------------------- */

/* --------------------------------------------------------- 同步至erp start --------------------------------------------------------- */
const confirmErpDiaProps = reactive({
    show: false,
    title: '',
    content: '商品已同步至ERP，请前往ERP中操作①设置期初库存；②店铺设置中，开启库存同步',
    contentAlign: 'left'
});
let loading = null;
const onSyncErp = throttle(
    async () => {
        const res = await request('erpSyncGoods');
        if (res.code === 0) {
            if (!loading) {
                loading = ElLoading.service({
                    lock: true,
                    text: '同步中...',
                    background: 'rgba(0, 0, 0, 0.7)'
                });
            }
            onSearchResult();
        } else if (res.code === 8080004) {
            ElMessage.error('ERP授权已过期，请前往系统设置-应用市场，重新授权');
        } else {
            ElMessage.error(res.msg || '服务异常，请稍后重试');
        }
    },
    4000,
    { trailing: false }
);
// 轮询查询同步结果
const onSearchResult = () => {
    const timer = setTimeout(async () => {
        const { data } = await request('erpSyncGoodsResult');
        if (data.syncStatus === 2) {
            clearTimeout(timer);
            loading.close();
            confirmErpDiaProps.show = true;
            await nextTick();
            ElMessage.success('同步成功');
        } else if (data.syncStatus === 3) {
            loading.close();
            await nextTick();
            ElMessage.error('同步失败');
        } else {
            onSearchResult();
        }
    }, 3000);
};
const onSyncDone = () => {
    confirmErpDiaProps.show = false;
    getList();
};
/* --------------------------------------------------------- 同步至erp end --------------------------------------------------------- */

/* --------------------------------------------------------- 发布商品 start --------------------------------------------------------- */
const addGoods = () => {
    router.push('/commodity/list/pub');
};
/* --------------------------------------------------------- 发布商品 end --------------------------------------------------------- */

/* --------------------------------------------------------- tab切换 start --------------------------------------------------------- */
const tabClick = ({ paneName }) => {
    state.currentTab = paneName;
    useCommodityStore.currentTab = paneName;
    const onSale = { 1: 1, 2: 3, 3: 2 };
    state.searchParams.onSale = onSale[paneName];
    getList();
};
/* --------------------------------------------------------- tab切换 end --------------------------------------------------------- */

onMounted(getList);
</script>
<style lang="scss" scoped>
.default-route {
    position: relative;

    nav {
        margin-top: -24px;
        margin-bottom: 24px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        &::after {
            content: '';
            position: absolute;
            top: 55px;
            left: 0;
            width: 100%;
            height: 1px;
            background-color: #dcdfe6;
        }
        :deep(.el-tabs) {
            .el-tabs__header {
                margin-bottom: 0;
                .el-tabs__nav-wrap {
                    &::after {
                        height: 0;
                    }
                    .el-tabs__nav-scroll {
                        .el-tabs__nav {
                            .el-tabs__active-bar {
                                height: 2px;
                                bottom: 0.5px;
                            }
                        }
                        .el-tabs__item {
                            height: 57px;
                            line-height: 57px;
                        }
                    }
                }
            }
        }
        .right_btn {
            .el-button:first-child {
                padding: 0 11px;
                .icon-img {
                    img {
                        width: 13px;
                        height: 13px;
                        margin-top: 1px;
                        margin-left: 6px;
                        &:nth-child(2) {
                            display: none;
                        }
                    }
                }
                &:hover {
                    .icon-img img {
                        &:nth-child(1) {
                            display: none;
                        }
                        &:nth-child(2) {
                            margin-top: -1px;
                            display: block;
                        }
                    }
                }
            }
        }
    }
    .btn_group {
        margin-bottom: 16px;
        text-align: right;
    }
}
</style>
